package com.ffs.persist.jdbc;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 不留遗憾，不负年华。
 *
 * 自定义jdbc模板
 *
 * @author ffs80 created 2021/8/4
 */
@SuppressWarnings("unused")
public class JdbcTemplate {

    private final DataSource ds;

    public JdbcTemplate(DataSource ds) {
        this.ds = ds;
    }

    /**
     * 单体查询
     */
    public <T> T query(String sql, RowMapper<T> mapper, Object... parameters) {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            con = ds.getConnection();
            ps = con.prepareStatement(sql);

            for (int i = 0; i < parameters.length; i++) {
                ps.setObject(i + 1, parameters[i]);
            }
            rs = ps.executeQuery();
            if (rs.next()) {
                return mapper.mapping(rs);
            }
        } catch (Exception e) {

        } finally {
            release(con, ps, rs, mapper);
        }

        return null;
    }

    /**
     * 集合查询
     */
    public <T> List<T> queryList(String sql, RowMapper<T> mapper, Object... parameters) {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            con = ds.getConnection();
            ps = con.prepareStatement(sql);

            for (int i = 0; i < parameters.length; i++) {
                ps.setObject(i + 1, parameters[i]);
            }
            rs = ps.executeQuery();

            List<T> ret = new ArrayList<>();
            while (rs.next()) {
                ret.add(mapper.mapping(rs));
            }
            return ret;
        } catch (Exception e) {

        } finally {
            release(con, ps, rs, mapper);
        }
        return Collections.emptyList();
    }

    /**
     * 单体更新
     */
    public int update(String sql, Object... parameters) {
        Connection con = null;
        PreparedStatement ps = null;

        try {
            con = ds.getConnection();
            ps = con.prepareStatement(sql);

            for (int i = 0; i < parameters.length; i++) {
                ps.setObject(i + 1, parameters[i]);
            }

            return ps.executeUpdate();

        } catch (Exception e) {

        } finally {
            release(con, ps, null, null);
        }

        return -1;
    }

    /**
     * 批量更新
     */
    public int[] updateBatch(String sql, List<Object[]> parameters) {
        Connection con = null;
        PreparedStatement ps = null;

        try {
            con = ds.getConnection();
            ps = con.prepareStatement(sql);

            for (Object[] object : parameters) {
                for (int i = 0; i < object.length; i++) {
                    ps.setObject(i + 1, object[i]);
                }
                ps.addBatch();
            }

            return ps.executeBatch();
        } catch (Exception e) {

        } finally {
            release(con, ps, null, null);
        }

        return null;
    }

    /**
     * 资源释放
     */
    private void release(Connection con, PreparedStatement ps, ResultSet rs, RowMapper<?> mapper) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {

            }
        }

        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {

            }
        }

        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {

            }
        }

        if (mapper != null) {
            mapper.release();
        }
    }
}
